import { ExportConfig, E_ButtonStatus_Suffix, E_Item_Type, E_Option, E_Prefix, E_Suffix, KeyButtonStatus, ValSuffix, } from './Common';
import PackageItem from './PackageItem';
import Utils from './Utils';

const fs = require('fs-extra');
const path = require('path')
const psd = require('psd');
const xmlbuilder = require('xmlbuilder');
const jpeg = require('jpeg-js');

export default class UIPackage
{
    private _cfg:ExportConfig;                                  //导出配置
    private _buildId:string;                                    //每个包有唯一的Id
    private _nextItemIndex:number;                              //创建item个数的idx
    private _texture_Reses:any[];                               //纹理列表
    private _component_Reses:any[];                             //组件列表
    private _sameDataTestHelper:{[index:string] : PackageItem}; //相同资源内容检测
    private _sameNameTestHelper:{[index:string] : number};      //相同名称检测

    private _comExportPath:string;                              //控件导出路径
    private _resExportPath:string;                              //资源导出路径
    private readonly _tmpDir:string = 'tmp';                 //临时路径
    private _comExportPathTmp:string;
    private _resExportPathTmp:string;
    private _resBuildId:string;                                 //资源导出Id

    public get buildId()
    {
        return this._buildId;
    }

    public get cfg():ExportConfig
    {
        return this._cfg;
    }

    constructor(cfg:ExportConfig)
    {
        this._buildId = Utils.getMd5(`${cfg.mainCom}${cfg.subCom}`,8);
        this._resBuildId = Utils.getMd5(`${cfg.mainCom}_Res`.toLowerCase(),8);
        this._nextItemIndex = 0;
        this._sameDataTestHelper = {};
        this._sameNameTestHelper = {};
        this._texture_Reses = [];
        this._component_Reses = [];

        this._cfg = cfg;
        this._comExportPath = path.join(this._cfg.outPath,this._cfg.mainCom,this._cfg.subCom);
        this._resExportPath = path.join(this._cfg.outPath,this._cfg.mainCom+'_Res');
        this._comExportPathTmp = path.join(this._tmpDir,this._cfg.mainCom,this._cfg.subCom);
        this._resExportPathTmp = path.join(this._tmpDir,this._cfg.mainCom+'_Res');
        fs.ensureDirSync(this._comExportPath);
        fs.ensureDirSync(this._resExportPath);
        Utils.rmDir(this._tmpDir);
        fs.ensureDirSync(this._comExportPathTmp);
        fs.ensureDirSync(this._resExportPathTmp);
    }

    private async loadResPackage()
    {
        let resXmlPath = path.join(this._resExportPath,"package.xml");
        let isResPackExist = Utils.isFileExist(resXmlPath);

        if(isResPackExist)
        {
            let xmlData = fs.readFileSync(path.join(this._resExportPath,'package.xml'), 'utf-8');
            let idNameArrs:string[] = xmlData.match(/<image(.*)>/g);
            let cnt = idNameArrs ? idNameArrs.length : 0;
            for (let i = 0; i < cnt; i++) 
            {
                let str = idNameArrs[i];
                if(str)
                {
                    let id = Utils.getValueByKey('id',str);
                    let fileName = Utils.getValueByKey('name',str);
                    let scale9Grid = Utils.getValueByKey('scale9grid',str); 
                    let dataForHash:any = null;
                    let packItem = new PackageItem(E_Item_Type.IMAGE,fileName,null,id);
                    packItem.existed = true;
                    let imgData:any = await Utils.getImgData(path.join(this._resExportPath,fileName));
                    if(fileName.indexOf('.jpg') != -1)
                    {
                        // console.log('imgData:',imgData);
                        dataForHash = Buffer.from(imgData.data);
                    }
                    else
                    {
                        if(scale9Grid)
                        {
                            let scale9Arr:number[] = scale9Grid.split(',').map(Number);
                            scale9Arr[4] = imgData.width - Number(scale9Arr[0]) - Number(scale9Arr[2]);
                            scale9Arr[5] = imgData.height - Number(scale9Arr[1]) - Number(scale9Arr[3]);
                            packItem.scale9Grid = scale9Arr;
                            let lastIdx = fileName.lastIndexOf('.');
                            let ext = fileName.substr(lastIdx);
                            let name = fileName.substr(0,lastIdx);
                            let dec = scale9Arr.join('_');
                            dataForHash = `${name}${E_Suffix.Grid9}${dec}${ext}`;
                        }
                        else
                        {
                            dataForHash = Buffer.from(imgData.data)
                        }
                    }
                    let hash:string = Utils.getMd5(dataForHash);
                    this._sameDataTestHelper[hash] = packItem;
                    this._texture_Reses.push(packItem);
                }
            }
        }
    }

    /**
     * 导出fgui包 [资源包+组件包]
     */
    public async exportPackge():Promise<UIPackage>
    {
        await this.loadResPackage();
        let psdPraser = psd.fromFile(this._cfg.psdFile);
        psdPraser.parse();
        let psdTree = psdPraser.tree();
        //console.log(JSON.stringify(psdTree.export()));
        let subComPackItem = this.createComponent(psdTree,this._cfg.subCom);
        subComPackItem.id = this._buildId; 
        return new Promise(async (resolve, reject) =>{
            let exportResOk = await this.exportResPackage();
            if(exportResOk)
            {
                console.log('res export ok->'+this._resExportPathTmp);
                let exportComOk = await this.exprotComPackage();
                if(exportComOk)
                {
                    console.log('com export ok->'+this._comExportPathTmp);
                    console.log(`copy ${this._tmpDir} to ${this._cfg.outPath}`);
                    Utils.copyDir(this._tmpDir,this._cfg.outPath);
                    console.log(`rmdir ${this._tmpDir}`);
                    Utils.rmDir(this._tmpDir);
                    console.log(`export finish!`);
                    resolve(this);        
                }
                else
                {
                    reject(null);
                }
            }
            else
            {
                reject(null);
            }
        });
    }

    /**
     * 导出资源包
     */
    private async exportResPackage():Promise<boolean>
    {
        if(this._comExportPath ==  this._resExportPath)
        {
            console.error('res buildId same with com build');
            return false;
        }
        let saveImg = async (item:PackageItem):Promise<void> =>{
            let outPath:string = path.join(this._resExportPathTmp, item.name);
            if(outPath.endsWith('jpg'))
            {
                return new Promise((resolve, reject) =>{
                    fs.writeFileSync(outPath, item.data.data);
                    resolve();
                });
            }
            else if(item.scale9Grid)
            {
               await item.format9ScaleData();
            }
            let pngPims = item.data.saveAsPng(outPath);
            return pngPims;
        }

        return new Promise((resolve, reject) =>{
            let savePromises = [];
            let pkgDesc = xmlbuilder.create('packageDescription');
            pkgDesc.att('id', this._resBuildId);
            let resourcesNode = pkgDesc.ele('resources');
            this._texture_Reses.forEach((item:PackageItem) => {
                let resNode = resourcesNode.ele(E_Item_Type.IMAGE);
                resNode.att('id', item.id)
                    .att('name', item.name)
                    .att('path', `/`)
                    .att('exported', true);
                if (item.scale9Grid) {
                    resNode.att('scale', '9grid');
                    resNode.att('scale9grid', item.scale9Grid);
                }

                if(!item.existed)
                {
                    savePromises.push(saveImg(item));
                }
            });
            savePromises.push(fs.writeFile(path.join(this._resExportPathTmp, 'package.xml'),
                    pkgDesc.end({ pretty: true })));
            Promise.all(savePromises).then(() => {
                resolve(true);
            }).catch(_ => reject(false));
        });
    }

    /**
     * 导出组件包
     */
    private async exprotComPackage():Promise<boolean>
    {
        let genNewFileData = (packagePath:string,fileData:string):string =>{
            let newFileData = fileData;
            let newComponets:RegExpMatchArray|null = newFileData.match(/<component(.*)>/g);
            if(newComponets && newComponets.length && Utils.isFileExist(packagePath))
            {
                let packData = fs.readFileSync(packagePath,'utf-8');
                let reg = /<resources>([\s\S]+)<\/resources>/g;
                let resources:RegExpMatchArray|null  = packData.match(reg);
                if(resources && resources.length)
                {
                    let componets:string[]|null = resources[0].match(/<(.*)\/>/g);
                    if(componets && componets.length > 0)
                    {
                        for(let i=0 , cnt = newComponets.length ; i < cnt ; i++)
                        {
                            let newComponet:string = newComponets[i];
                            const newName:string = Utils.getValueByKey('name',newComponet);
                            const newPath:string = Utils.getValueByKey('path',newComponet);
                            let findCompont = componets.find((val:string,_idx:number,comps:string[])=>{
                                const name:string = Utils.getValueByKey('name',val);
                                const path:string = Utils.getValueByKey('path',val);
                                if(name == newName && path == newPath)
                                {
                                    comps[_idx] = newComponet;
                                    return val;
                                }
                            });

                            if(!findCompont)
                            {
                                componets.push(newComponet);
                            }
                        }

                        let componentStr = `<resources>\n\t` + componets.join('\n\t') + `\n  </resources>`;
                        newFileData = packData.replace(reg,componentStr);
                    }
                }
            }
            return newFileData;
        }; 

        return new Promise((resolve, reject) =>{
            let pkgDesc = xmlbuilder.create('packageDescription');
            pkgDesc.att('id', this._buildId);
            let resourcesNode = pkgDesc.ele('resources');
            let savePromises = [];
            this._component_Reses.forEach((item:PackageItem) => {
                let resNode = resourcesNode.ele(item.type);
                resNode.att('id', item.id).att('name', item.name).att('path', `/${this._cfg.subCom}/`);
                savePromises.push(fs.writeFile(path.join(this._comExportPathTmp, item.name), item.data));
            });

            let filePathTmp = path.join(this._tmpDir,this._cfg.mainCom, 'package.xml');
            let desFilePath = path.join(this._cfg.outPath,this._cfg.mainCom, 'package.xml');
            let packageFileData = genNewFileData(desFilePath,pkgDesc.end({ pretty: true }));
            savePromises.push(fs.writeFile(filePathTmp,packageFileData));

            Promise.all(savePromises).then(() => {
                resolve(true);
            }).catch(_ => reject(false));
        });
    }

    /**
     * 组件id
     */
    private getNextItemId():string
    {
        return this._buildId + (this._nextItemIndex++).toString(36);
    }

    /**
     * 创建组件
     * @param aNode 
     * @param name 
     */
    private createComponent(aNode:any, name:string = '') : PackageItem
    {
        let component = xmlbuilder.create('component');
        component.att('size', aNode.get('width') + ',' + aNode.get('height'));
        let displayList = component.ele('displayList');
    
        let cnt = aNode.children().length;
        for (let i = cnt - 1; i >= 0; i--) 
        {
            this.parseNode(aNode.children()[i], aNode, displayList);
        }

        return this.createPackageItem(E_Item_Type.COMPONENT, (name ? name : aNode.get('name')) + '.xml', component.end({ pretty: true }));
    }

    /**
     * 创建进度条
     * @param aNode 
     */
    private createProgressBar(aNode:any):PackageItem
    {
        let component = xmlbuilder.create('component');
        component.att('size', aNode.get('width') + ',' + aNode.get('height'));
        component.att('extention', 'ProgressBar');

        let onElementCallback =  (child:any, node:any) => {
            let nodeName = node.get('name');
            if (nodeName.indexOf(E_Suffix.BAR) != -1) 
            {
                child.att('name','bar');
            }
        };

        let displayList = component.ele('displayList');
        for (let i = aNode.children().length - 1; i >= 0; i--) 
        {
            this.parseNode(aNode.children()[i], aNode, displayList, onElementCallback);
        }

        return this.createPackageItem(E_Item_Type.COMPONENT, aNode.get('name') + '.xml', component.end({ pretty: true }));
    }

    /**
     * 创建按钮组件
     * @param aNode 
     * @param instProps 显示属性
     */
    private createButton(aNode:any, instProps:ValSuffix) 
    {
        let component = xmlbuilder.create('component');
        component.att('size', aNode.get('width') + ',' + aNode.get('height'));
        component.att('extention', 'Button');
    
        let btnStatuesImgs:any[] = [];
        let imagePages:any[] = [];
        aNode.descendants().forEach( (childNode:any) => {
            let nodeName = childNode.get('name');
            let idx = 0;
            for (let i in E_ButtonStatus_Suffix) 
            {
                let key = i as KeyButtonStatus;
                if (nodeName.indexOf(E_ButtonStatus_Suffix[key]) != -1) 
                {
                    btnStatuesImgs[idx] = childNode;
                }
                idx++;
            };
        });

        if(btnStatuesImgs.length > 1)
        {
            imagePages[0] = [0,2];
            imagePages[1] = [1,3];
            imagePages[2] = [1,3];
        }
        else
        {
            imagePages[0] = [0,1,2,3];
        }
    
        let onElementCallback =  (child:any, node:any) => {
            let j = btnStatuesImgs.indexOf(node);
            if (j != -1) 
            {
                let gear = child.ele('gearDisplay');
                gear.att('controller', 'button');
                gear.att('pages', imagePages[j].join(','));
            }
    
            if (child.attributes['text']) 
            {
                child.att('name','title');
                instProps[E_Suffix.TITLE] = child.attributes['text'].value;
                instProps['@titleColor'] = child.attributes['color'].value;
                // child.removeAttribute('text');
            }
            else if (child.attributes['url']) 
            {
                instProps[E_Suffix.ICON] = child.attributes['url'].value;
                // child.removeAttribute('url');
            }
        };
    
        let controller = component.ele('controller');
        controller.att('name', 'button');
        controller.att('pages', '0,up,1,down,2,over,3,selectedOver');
    
        let displayList = component.ele('displayList');
        for (let i = aNode.children().length - 1; i >= 0; i--) 
        {
            let child = aNode.children()[i];
            this.parseNode(child, aNode, displayList, onElementCallback);
        }
    
        let extension = component.ele('Button');
        if (aNode.get('name').indexOf(E_Prefix.CHECKBUTTON) == 0) 
        {
            extension.att('mode', 'Check');
            instProps[E_Suffix.CHECKED] = 'true';
        }
        else if (aNode.get('name').indexOf(E_Prefix.RADIOBUTTON) == 0)
        {
            extension.att('mode', 'Radio');
        }
    
        if (btnStatuesImgs.length <= 1) 
        {
            extension.att('downEffect', 'scale');
            extension.att('downEffectValue', '1.1');
        }
    
        return this.createPackageItem(E_Item_Type.COMPONENT, aNode.get('name') + '.xml', component.end({ pretty: true }));
    }

    /**
     * 创建img
     * @param aNode 
     * @param scale9Grid 
     */
    private createImage(aNode:any):PackageItem
    {
        let width:number = aNode.get('width');
        let height:number = aNode.get('height');
        //超大图片保存为jpg
        let imgSuffix = (width > 1024 || height > 1024) ? `_${this._cfg.subCom}.jpg` : '.png';
        let nodeName = aNode.get('name');
        let fFileName = Utils.formatFileName(nodeName);
        let scale9Grid:number[] | undefined;
        if(nodeName.indexOf(E_Suffix.Grid9) != -1)
        {
            let pattern = new RegExp(`${E_Suffix.Grid9}([0-9|_]+)`, "g");
            let s9InfoArr:RegExpMatchArray|null = nodeName.match(pattern);
            let s9Info:string = s9InfoArr ? s9InfoArr[0].substr(E_Suffix.Grid9.length) : '';
            let s9Cfg:string[] = s9Info.split('_');
            if(s9Cfg.length >= 1)
            {
                let left =  Number(s9Cfg[0]);
                if(left < width && left < height)
                {
                    let up = Number(s9Cfg[1] || left);
                    let middleWidth = Number(s9Cfg[2] || 4);
                    let middleHeight = Number(s9Cfg[3] || middleWidth);
                    let right = Number(s9Cfg[4] || left);
                    let bottom = Number(s9Cfg[5] || up);
                    scale9Grid = [left,up,middleWidth,middleHeight,right,bottom];
                    let dec = scale9Grid.join('_');
                    fFileName = fFileName + `${E_Suffix.Grid9}${dec}`;
                }
            }
        }
        let fileName = `${fFileName}${imgSuffix}`
        let packageItem = this.createPackageItem(E_Item_Type.IMAGE,fileName, aNode);
        packageItem.scale9Grid = scale9Grid;
        return packageItem;
    }
    
    private isButton(nodeName:string):boolean
    {
        if(!nodeName) return false;
        return nodeName.indexOf(E_Prefix.BUTTON) == 0 || nodeName.indexOf(E_Prefix.CHECKBUTTON) == 0 || nodeName.indexOf(E_Prefix.RADIOBUTTON) == 0;
    }

    /**
     * 创建组件xml
     */
    private createXmlComponent(aNode:any, rootNode:any,displayList:any,packageItem:PackageItem):any
    {
        let child = xmlbuilder.create('component');
        let str = 'n' + (displayList.children.length + 1);
        child.att('id', str + '_' + this._buildId);
        child.att('name', str);
        child.att('src', packageItem.id);
        child.att('fileName', packageItem.name);
        child.att('xy', (aNode.left - rootNode.left) + ',' + (aNode.top - rootNode.top));
        return child;
    }

    /**
     * 创建进度条xml
     */
    private createXmlProgressBar(aNode:any, rootNode:any,displayList:any,packageItem:PackageItem,specialUsage:string | null):any
    {
        let child = xmlbuilder.create('component');
        let str = 'n' + (displayList.children.length + 1);
        child.att('id', str + '_' + this._buildId);
        child.att('name', specialUsage ? specialUsage : str);
        child.att('src', packageItem.id);
        child.att('fileName', packageItem.name);
        child.att('xy', (aNode.left - rootNode.left) + ',' + (aNode.top - rootNode.top));
        child.ele({ ProgressBar: {'@value':50,'@max':100} });
        return child;
    }

    /**
     * 创建按钮xml
     */
    private createXmlButton(aNode:any, rootNode:any,displayList:any,packageItem:PackageItem , instProps:ValSuffix):any
    {
        let child = xmlbuilder.create('component');
        let str = 'n' + (displayList.children.length + 1);
        child.att('id', str + '_' + this._buildId);
        child.att('name', str);
        child.att('src', packageItem.id);
        child.att('fileName', packageItem.name);
        child.att('xy', (aNode.left - rootNode.left) + ',' + (aNode.top - rootNode.top));
        child.ele({ Button: instProps });
        return child;
    }

    /**
     * 创建文本xml
     */
    private createXmlText(aNode:any, rootNode:any,displayList:any,typeTool:any,specialUsage:string | null):any
    {
        let child = xmlbuilder.create('text');
        let str = 'n' + (displayList.children.length + 1);
        child.att('id', str + '_' + this._buildId);
        child.att('name', specialUsage ? specialUsage : str);
        child.att('text', typeTool.textValue);
        if (specialUsage == 'title') 
        {
            child.att('xy', (aNode.left - rootNode.left - 4) + ','  + (aNode.top - rootNode.top - 4));
            child.att('size', rootNode.width + ',' + (aNode.height + 8));
            child.att('align', 'center').att('vAlign','middle');
            let relation = xmlbuilder.create('relation');
            relation.att('target','').att('sidePair','center-center,middle-middle');
            child.importDocument(relation);
        }
        else 
        {
            child.att('xy', (aNode.left - rootNode.left - 4) + ',' + (aNode.top - rootNode.top - 4));
            child.att('size', (aNode.width + 8) + ',' + (aNode.height + 8));
            str = typeTool.alignment()[0];
            if (str != 'left')
            {
                child.att('align', str);
            }
        }
        child.att('vAlign', 'middle');
        // child.att('autoSize', 'none');
        if (!(this._cfg.option & E_Option.IGNORE_FONT))
        {
            child.att('font', typeTool.fonts()[0]);
        }
            
        child.att('fontSize', typeTool.sizes()[0]);
        child.att('color', Utils.convertToHtmlColor(typeTool.colors()[0]));
        return child;
    }
    
    /**
     * 创建图片xml
     */
    private createXmlImage(aNode:any, rootNode:any,displayList:any,packageItem:PackageItem,specialUsage:string | null):any
    {
        let typeName = (specialUsage == 'icon' ? 'loader' : 'image');
        let child = xmlbuilder.create(typeName);
        let str = 'n' + (displayList.children.length + 1);
        child.att('id', str + '_' + this._buildId);
        let name = str;
        if(specialUsage)
        {
            name = this.isButton(rootNode.get('name')) ?  specialUsage : name+"_icon";
        } 
        child.att('name', name);
        child.att('xy', (aNode.left - rootNode.left) + ',' + (aNode.top - rootNode.top));
        let sidePair = '';
        if (specialUsage == 'icon') 
        {
            child.att('size', aNode.width + ',' + aNode.height);
            child.att('url', 'ui://' + this._resBuildId + packageItem.id);
            child.att('fill','scaleFree').att('align','center')
                .att('vAlign','middle').att('autoSize','true')
                .att('pivot','0.5,0.5');
            sidePair = 'center-center,middle-middle';
        }
        else
        {
            child.att('src', packageItem.id);
            child.att('pkg',this._resBuildId);
            sidePair = 'width-width,height-height';
            child.att('fileName', packageItem.name);
        }
        
        //9宫居中放大缩小
        if(packageItem.scale9Grid)
        {
            child.att('size', aNode.width + ',' + aNode.height);
            let relation = xmlbuilder.create('relation');
            relation.att('target','').att('sidePair',sidePair);
            child.importDocument(relation);
        }

        return child;
    }

    private  parseNode(aNode:any, rootNode:any, displayList:any, onElementCallback:Function|null = null) 
    {
        if(!aNode.visible()) return;
        let nodeName = aNode.get('name');
        let specialUsage:string = '' , child:any = null;
        if (nodeName.indexOf(E_Suffix.TITLE) != -1)
        {
            specialUsage = 'title';
        }
        else if (nodeName.indexOf(E_Suffix.ICON) != -1)
        {
            specialUsage = 'icon';
        }
    
        if (aNode.isGroup()) 
        {
            if (nodeName.indexOf(E_Prefix.COMPONENT) == 0) 
            {
                let packageItem:PackageItem = this.createComponent(aNode);
                child = this.createXmlComponent(aNode,rootNode,displayList,packageItem);
            }
            else if(nodeName.indexOf(E_Prefix.PROGRESSBAR) == 0)
            {
                let packageItem:PackageItem = this.createProgressBar(aNode);
                child = this.createXmlProgressBar(aNode,rootNode,displayList,packageItem,specialUsage);  
            }
            else if (this.isButton(nodeName)) 
            {
                let instProps:ValSuffix = {};
                let packageItem:PackageItem = this.createButton(aNode, instProps);
                child = this.createXmlButton(aNode,rootNode,displayList,packageItem,instProps);
            }
            else 
            {
                for (let i = aNode.children().length - 1; i >= 0; i--)
                {
                    this.parseNode(aNode.children()[i], rootNode, displayList, onElementCallback);
                }
            }
        }
        else 
        {
            let typeTool = aNode.get('typeTool');
            if (typeTool) 
            {
                child = this.createXmlText(aNode,rootNode,displayList,typeTool,specialUsage);
            }
            else if (!aNode.isEmpty()) 
            {
                let packageItem:PackageItem = this.createImage(aNode);
                child = this.createXmlImage(aNode,rootNode,displayList,packageItem,specialUsage);
            }
        }
    
        if (child) 
        {
            let opacity = aNode.get('opacity');
            if (opacity < 255)
            {
                child.att('alpha', (opacity / 255).toFixed(2));
            }
            onElementCallback && onElementCallback(child, aNode);
            displayList.importDocument(child);
        }

        return child;
    }

    /**
     * 创建包
     * @param type 类型
     * @param fileName 文件名
     * @param data 
     */
    private createPackageItem(type:E_Item_Type, fileName:string, data:any) 
    {
        let dataForHash = data , resources = this._component_Reses;
        if(type == E_Item_Type.IMAGE)
        {
            dataForHash = Buffer.from(data.get('image').pixelData);
            if(fileName.indexOf('.jpg') != -1)
            {
                let rawImageData = {
                    data: dataForHash,
                    width: data.width,
                    height: data.height,
                };
                data = jpeg.encode(rawImageData);
                let pixelData = jpeg.decode(data.data, {useTArray: true});
                // console.log('pixelData',pixelData);
                dataForHash = Buffer.from(pixelData.data);
            }
            else if(fileName.indexOf(E_Suffix.Grid9) != -1)
            {
                //九宫格直接使用名称做hash
                dataForHash = fileName;
            }
            resources = this._texture_Reses;
        }
        else if(type == E_Item_Type.COMPONENT)
        {
            dataForHash = dataForHash.replace(/(\s{1,1})url="(.*?)"/g,  '');    //默认url
            dataForHash = dataForHash.replace(/(\s{1,1})text="(.*?)"/g, '');    //默认文本
            dataForHash = dataForHash.replace(/(\s{1,1})xy="(.*?)"/g,   '');    //默认位置
            dataForHash = dataForHash.replace(/(\s{1,1})size="(.*?)"/g, '');    //默认size
            dataForHash = dataForHash.replace(/(\s{1,1})color="(.*?)"/g,'');    //color
            dataForHash = dataForHash.replace(/(\s{1,1})src="(.*?)"/g,'');      //默认图片
            dataForHash = dataForHash.replace(/(\s{1,1})fileName="(.*?)"/g,''); //默认图片
            dataForHash += fileName;
        }
        let id = this.getNextItemId();
        let hash:string = Utils.getMd5(dataForHash);
        let item = this._sameDataTestHelper[hash];
        if (!item) 
        {
            fileName = Utils.formatFileName(fileName.replace('-','_'));
            let i = fileName.lastIndexOf('.');
            let basename = fileName.substr(0, i);
            //basename = basename.replace(/[\@\'\'\\\/\b\f\n\r\t\$\%\*\:\?\<\>\|]/g, '_');
            let ext = fileName.substr(i);
            while (true) 
            {
                let j = this._sameNameTestHelper[basename];
                if (j) 
                {
                    this._sameNameTestHelper[basename] = j + 1;
                    basename = basename + '_' + j;
                }
                else 
                {
                    this._sameNameTestHelper[basename] = 1;
                    break;
                }
            }
            fileName = basename + ext;
            item = new PackageItem(type,fileName,data,id)
            resources.push(item);
            this._sameDataTestHelper[hash] = item;
        }
        return item;
    }
}